{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "bc09bb11-d2fa-4d22-8952-913c70becbf7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch \n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "522086c6-0d50-44af-8f68-7e2110d4e08e",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = pd.read_csv('data/credit-a.csv',header = None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "b233d142-8902-4040-b46d-58a1b085da7c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 653 entries, 0 to 652\n",
      "Data columns (total 16 columns):\n",
      " #   Column  Non-Null Count  Dtype  \n",
      "---  ------  --------------  -----  \n",
      " 0   0       653 non-null    int64  \n",
      " 1   1       653 non-null    float64\n",
      " 2   2       653 non-null    float64\n",
      " 3   3       653 non-null    int64  \n",
      " 4   4       653 non-null    int64  \n",
      " 5   5       653 non-null    int64  \n",
      " 6   6       653 non-null    int64  \n",
      " 7   7       653 non-null    float64\n",
      " 8   8       653 non-null    int64  \n",
      " 9   9       653 non-null    int64  \n",
      " 10  10      653 non-null    int64  \n",
      " 11  11      653 non-null    int64  \n",
      " 12  12      653 non-null    int64  \n",
      " 13  13      653 non-null    int64  \n",
      " 14  14      653 non-null    float64\n",
      " 15  15      653 non-null    int64  \n",
      "dtypes: float64(4), int64(12)\n",
      "memory usage: 81.8 KB\n"
     ]
    }
   ],
   "source": [
    "data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "6ea40d82-ef72-433f-890f-40eba887dc74",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "      <th>6</th>\n",
       "      <th>7</th>\n",
       "      <th>8</th>\n",
       "      <th>9</th>\n",
       "      <th>10</th>\n",
       "      <th>11</th>\n",
       "      <th>12</th>\n",
       "      <th>13</th>\n",
       "      <th>14</th>\n",
       "      <th>15</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>30.83</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>9</td>\n",
       "      <td>0</td>\n",
       "      <td>1.25</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>202</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>58.67</td>\n",
       "      <td>4.460</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>1</td>\n",
       "      <td>3.04</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>6</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>43</td>\n",
       "      <td>560.0</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>24.50</td>\n",
       "      <td>0.500</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>1</td>\n",
       "      <td>1.50</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>280</td>\n",
       "      <td>824.0</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>27.83</td>\n",
       "      <td>1.540</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>9</td>\n",
       "      <td>0</td>\n",
       "      <td>3.75</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>100</td>\n",
       "      <td>3.0</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>20.17</td>\n",
       "      <td>5.625</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>9</td>\n",
       "      <td>0</td>\n",
       "      <td>1.71</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>120</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   0      1      2   3   4   5   6     7   8   9   10  11  12   13     14  15\n",
       "0   0  30.83  0.000   0   0   9   0  1.25   0   0   1   1   0  202    0.0  -1\n",
       "1   1  58.67  4.460   0   0   8   1  3.04   0   0   6   1   0   43  560.0  -1\n",
       "2   1  24.50  0.500   0   0   8   1  1.50   0   1   0   1   0  280  824.0  -1\n",
       "3   0  27.83  1.540   0   0   9   0  3.75   0   0   5   0   0  100    3.0  -1\n",
       "4   0  20.17  5.625   0   0   9   0  1.71   0   1   0   1   2  120    0.0  -1"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "569d4e2e-8f0f-44b9-8388-41ff2d28e107",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = data.iloc[:,:-1]  # 取出所有特征数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "48560e81-9ce9-429a-b0ad-e9b6058c479f",
   "metadata": {},
   "outputs": [],
   "source": [
    "Y = data.iloc[:,-1].replace(-1,0) # 去除最后一列 结果数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "64237ed1-30fd-4cec-9d67-6f3c8f7fb5c2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1], dtype=int64)"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y.unique() # 看下有几种数据(去重)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "d0568ec5-40bc-4a97-8077-9855e373d85d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(653, 15)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "e9cb1934-bd56-4bc9-8c05-b473e271f9a7",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = torch.from_numpy(X.values).type(torch.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "617287b8-8e3c-434d-8b66-73f3c83abafc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([653, 15])"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "20aa6a6d-e6ef-449d-8bab-a7af57fbbcf1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(653,)"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "366570df-354a-4053-b907-c1a879f8df51",
   "metadata": {},
   "outputs": [],
   "source": [
    "Y = torch.from_numpy(Y.values.reshape(-1,1)).type(torch.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "e2bcea12-8dd9-423c-bb37-511a901e9890",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([653, 1])"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y.size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "b16e3cc0-c253-44d6-997b-c9bff5d46d51",
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch import nn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "id": "7f43772c-1eec-4ea5-ac30-8e19def46105",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = nn.Sequential(\n",
    "    nn.Linear(15,1), # 输入15个特征  一个输出\n",
    "    nn.Sigmoid()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "f474cdc1-81cc-46c7-99ce-8e50b6710b01",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Sequential(\n",
       "  (0): Linear(in_features=15, out_features=1, bias=True)\n",
       "  (1): Sigmoid()\n",
       ")"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "id": "dd8dcc55-9f0d-4fa9-ae58-06113a27902e",
   "metadata": {},
   "outputs": [],
   "source": [
    "loss_fn = nn.BCELoss() # 二元交叉熵损失 ，输出都是 0，1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "56154110-ffea-4e53-8eb1-0dfe5ae5959b",
   "metadata": {},
   "outputs": [],
   "source": [
    "opt = torch.optim.Adam(model.parameters(),lr=0.001) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "id": "3868e8b4-4a11-40f0-999e-65c7be04e362",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 尽量用真实的数据分批次进行训练\n",
    "batches = 16 # 16组数据，实际数据要能够整除\n",
    "no_of_batch = 653 // 16 # 取整"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "id": "bfeedb39-6e5e-4787-835a-6099291acf2e",
   "metadata": {},
   "outputs": [],
   "source": [
    "for epoch in range(1000):\n",
    "    for i in range(no_of_batch):\n",
    "        start= i*batches # 抽样 、 跳跃式抽样\n",
    "        end = start + batches\n",
    "        # 以下的xy就是从元数据中提取抽样数据\n",
    "        x = X[start:end]\n",
    "        y = Y[start:end]\n",
    "        y_pred = model(x)\n",
    "        loss = loss_fn(y_pred,y)\n",
    "        opt.zero_grad()\n",
    "        loss.backward()\n",
    "        opt.step()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "99c4a954-81cc-48e1-a567-e7d6dc734e86",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "OrderedDict([('0.weight',\n",
       "              tensor([[-3.1854e-01, -1.0837e-02,  3.4515e-02,  2.5158e-01,  2.7302e-01,\n",
       "                       -8.3458e-03,  2.1239e-01, -1.5665e-01,  4.4709e+00,  2.2679e-01,\n",
       "                       -1.5580e-01, -3.1795e-01, -2.2137e-01,  2.0694e-03,  9.9398e-05]])),\n",
       "             ('0.bias', tensor([-0.2907]))])"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.state_dict() # w1*x1 + w2*x2 ...w15*x15"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "id": "8e108282-7b4a-405f-8d75-60cff9201f3c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8468606431852986"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "((model(X).data.numpy() > 0.5).astype('int') == Y.numpy()).mean()  # 预测结果 与实际结果比较; 然后结果求平均"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ff59d81e-9f2d-4681-bfed-fbf639114faa",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
